#define F_CPU 1.0e6  // 1 MHz

/****************************************************************************

   _                          _               
  (_)_ __  ___  ___ _ __   __| | ___ _ __ ___ 
  | | '__|/ __|/ _ \ '_ \ / _` |/ _ \ '__/ __|
  | | |   \__ \  __/ | | | (_| |  __/ | | (__ 
  |_|_|___|___/\___|_| |_|\__,_|\___|_|(_)___|
     |_____|                                  

  Copyright 2010 Jacques Supcik, Sc.D., Dipl. Informatik-Ing. ETHZ

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. 

 ***************************************************************************/

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <util/delay.h>

/*

   I will use the Internal PLL to generate a peripherical clock
   frequency of 8MHz.

   Here is a summary of the timing specification of the TSOP2236
   IR Reciver that we use on the other side:

   * Burst length should be 10 cycles/burst or longer.
   * After each burst which is between 10 cycles and 70
     cycles a gap time of at least 14 cycles is necessary.
   * For each burst which is longer than 1.0 ms a corresponding
     gap time is necessary at some time in the
     data stream. This gap time should be at least 4 times
     longer than the burst.

     In the first release of the sender, we used a burst of 20 cyles (555us)
     and a gap of 100 cycles (2'775us) for a total period of 3.33ms.
     In this release, we use the values at the limit of the specification
     in order to make the cell as fast as possible.

*/

#define FREQ1 222   // 8.0e6/222 = 36.036 kHz
#define BURST 20    // BURST*FREQ1/8.0e6 = 555us
#define GAP   25    // GAP*FREQ1/8.0e6 = 694us
//      TOTAL          1.25ms

#define LED    PB0
#define INPUT  PB2
#define OUTPUT PB3

volatile uint8_t counter;

ISR(TIMER1_OVF_vect) {
    counter++;
    if (counter >= BURST + GAP) {
        if (PINB & _BV(INPUT)) {
          TCCR1 |= _BV(COM1A0);
          PORTB &= ~_BV(OUTPUT);
        } else {
          PORTB |= _BV(OUTPUT);
        }
        counter = 0;
    } else if (counter == BURST) {
        TCCR1 &= ~_BV(COM1A0);
    }
}

ISR(BADISR_vect) {
}

int main(void) {
    counter = BURST + GAP;
    OCR1C = FREQ1;
    OCR1A = FREQ1/2;                    // 50% duty cycle
    PLLCSR |= _BV(PLLE);                // Start PLL mode
    _delay_us(100);                     // Wait 100us
    while (!(PLLCSR & _BV(PLOCK))) {}   // Wait for PLL to lock
    PLLCSR |= _BV(PCKE);                // Use PLL for timer1
    TIMSK |= _BV(TOIE1);                // Enable Timer Overflow Interrupt
    TCCR1 |= _BV(CS12) | _BV(PWM1A);    // Prescale 8 and PWM enabled
    DDRB  |= _BV(LED) | _BV(OUTPUT);
    PORTB |= 0x3F;                      // all on (output + pull ups)
    sei();

    for (;;)
        sleep_mode();

    return 0;
}

